/*
* video_homography.cpp
*
*  Created on: Oct 18, 2010
*      Author: erublee
*/

#include "opencv2/highgui.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <fstream>
#include <list>
#include <bitset>
#include <vector>
#include <string>
#include <map>

using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;

int main(int ac, char ** av)
{
    const string img_file = "D:/images/zoom-rotation-boat/img1.pgm";
    //cv::Ptr<cv::Feature2D> sift = cv::xfeatures2d::SIFT::create();
    cv::Ptr<cv::BRISK> brisk = cv::BRISK::create(50, 3, 1.0f);

    std::vector<KeyPoint> keypoints_sift, keypoints_brisk;
    keypoints_sift.reserve(20000);
    keypoints_brisk.reserve(20000);

    auto img = cv::imread(img_file, cv::IMREAD_GRAYSCALE);
    cv::Mat desc;
    brisk->detectAndCompute(img, cv::Mat(), keypoints_brisk, desc);
    //brisk->compute(img, keypoints_brisk, desc);

    cv::Mat img_integral; // the integral image
    cv::integral(img, img_integral);
    std::vector<int> rgb;

    std::string brisk_gray_result("D:/Program Files/opencv/vsbuild/brisk_gray.txt");
    std::ofstream ofs(brisk_gray_result);

    std::vector<std::pair<unsigned int, unsigned int>> short_pairs;
    brisk->shortPair(short_pairs);

    const auto& key_desc = desc.row(0);
    for (int i = 0; i < desc.cols; ++i) {
      auto byte_desc = key_desc.at<unsigned char>(0, i);
      std::cout << std::bitset<8>(byte_desc) << " ";
    }
    std::cout << std::endl;

    brisk->smoothedIntensity(img, img_integral, keypoints_brisk[0], rgb);
    for (int i = 0; i < 64; ++i) {
      int byte_desc = 0;
      for (int j = 0; j < 8; ++j) {
        const auto& cur_pair = short_pairs[8 * i + j];
        if (rgb[cur_pair.first] > rgb[cur_pair.second]) {
          byte_desc |= (1 << j);
        }
      }
      std::cout << std::bitset<8>(byte_desc) << " ";
    }
    std::cout << std::endl;

    for (const auto& kp : keypoints_brisk) {
      brisk->smoothedIntensity(img, img_integral, kp, rgb);
      ofs << kp.size << " " << kp.angle << " ";
      for (const auto& val : rgb) {
        ofs << val << " ";
      }
      ofs << std::endl;
    }
    ofs.close();

    return 0;
}
